/**
 * 
 */
package cn.damong.utils.collections;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * <p>类的工具类，主要用于打印任何类的对象以及抽取类的成员变量<p>
 * 
 * 打印级别为DEBUG
 * 
 * @author CodingPanda
 * @2019年5月15日 下午11:09:17
 *
 */
@SuppressWarnings("rawtypes")
public class ClassUtil {
	private static Logger logger = LoggerFactory.getLogger(ClassUtil.class);

	private static Set<String> simpleClassNameSet = new HashSet<String>();
	static {
		simpleClassNameSet.add("int");
		simpleClassNameSet.add("short");
		simpleClassNameSet.add("long");
		simpleClassNameSet.add("float");
		simpleClassNameSet.add("double");
		simpleClassNameSet.add("Integer");
		simpleClassNameSet.add("Short");
		simpleClassNameSet.add("Long");
		simpleClassNameSet.add("Double");
		simpleClassNameSet.add("Float");
		simpleClassNameSet.add("boolean");
		simpleClassNameSet.add("Boolean");
		simpleClassNameSet.add("String");
	}
	
	private static Map<String, Object> defaultValueMap = new HashMap<String, Object>();
	static {
		defaultValueMap.put("int", 0);
		defaultValueMap.put("short", 0);
		defaultValueMap.put("long", 0l);
		defaultValueMap.put("float", 0f);
		defaultValueMap.put("double", 0.0);
		defaultValueMap.put("Integer", 0);
		defaultValueMap.put("Short", 0);
		defaultValueMap.put("Long", 0l);
		defaultValueMap.put("Double", 0.0);
		defaultValueMap.put("Float", 0f);
		defaultValueMap.put("boolean", false);
		defaultValueMap.put("Boolean", false);
		defaultValueMap.put("String", "");
	}

	/**
	 * 直接打印对象, DEBUG级别日志
	 * @param o
	 */
	public static void print(Object o) {
		print(o, true);
	}
	
	/**
	 * 直接打印对象, DEBUG级别日志
	 * @param o
	 */
	public static void print(Object o, Logger logger) {
		print(o, true, logger);
	}

	/**
	 * 直接打印对象, DEBUG级别日志
	 * @param o
	 */
	
	public static void print(Object o, Boolean printNullField) {
		if (o == null) {
			return;
		}
		Class c = o.getClass();
		if (simpleClassNameSet.contains(c.getSimpleName())) {
			logger.debug(o.toString());;
		} else {
			try {
				Field[] fields = c.getDeclaredFields();
				StringBuffer sb = new StringBuffer();
				for (Field f : fields) {
					if (f.getName().equalsIgnoreCase("serialVersionUID")) {
						continue;
					}
					f.setAccessible(true);
					Object value = f.get(o);
					if (value == null) {
						if (printNullField != null && printNullField) {
							sb.append(f.getName() + ":null\t");
						} else {
							continue;
						}
					} else {
						sb.append(f.getName() + ":" + value + "\t");
					}
				}
				logger.debug(sb.toString());
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 直接打印对象
	 * @param o
	 */
	public static void print(Object o, Boolean printNullField, Logger logger) {
		if (o == null) {
			return;
		}
		Class c = o.getClass();
		if (simpleClassNameSet.contains(c.getSimpleName())) {
			logger.debug(o.toString());;
		} else {
			try {

				Field[] fields = c.getDeclaredFields();
				StringBuffer sb = new StringBuffer();
				for (Field f : fields) {
					if (f.getName().equalsIgnoreCase("serialVersionUID")) {
						continue;
					}
					f.setAccessible(true);
					Object value = f.get(o);
					if (value == null) {
						if (printNullField != null && printNullField) {
							sb.append(f.getName() + ":null\t");
						} else {
							continue;
						}
					} else {
						sb.append(f.getName() + ":" + value + "\t");
					}
				}
				logger.debug(sb.toString());
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 直接打印对象,只打印指定的field
	 * @param o
	 * Set<String> fieldSet  传入小写的field Name Set
	 */
	public static void print(Object o, Set<String> fieldSet) {
		if (o == null) {
			return;
		}
		try {
			Class c = o.getClass();
			Field[] fields = c.getDeclaredFields();
			StringBuffer sb = new StringBuffer();
			for (Field f : fields) {
				if (f.getName().equalsIgnoreCase("serialVersionUID")) {
					continue;
				}
				if (!fieldSet.contains(f.getName().toLowerCase())) {
					continue;
				}
				f.setAccessible(true);
				Object value = f.get(o);
				if (value == null) {
					continue;
				}
				sb.append(f.getName() + ":" + value + "\t");
			}
			logger.debug(sb.toString());
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 提取指定对象所有声明的属性名, 不包含serialVersionUID
	 * @param object 对象
	 * @return 所有属性名集合
	 */
	public static Set<String> extractFields(Object object) {
		if(null == object) {
			return null;
		}
		
		return extractFields(object.getClass());
	}

	/**
	 * 提取指定对象所有声明的属性名, 不包含serialVersionUID
	 * @param clz 类
	 * @return 所有属性名集合
	 */
	public static Set<String> extractFields(Class<?> clz){
		if (clz == null) {
			return null;
		}
		
		Set<String> fieldsSet = new HashSet<String>();
		try {
			Field[] fields = clz.getDeclaredFields();
			for (Field f : fields) {
				fieldsSet.add(f.getName());
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		}
		fieldsSet.remove("serialVersionUID");
		return fieldsSet;
	}

	/**
	 * 将一个对象的NULL属性设置默认值
	 * @param o
	 */
	public static void fillNullValue(Object o){
		if (o == null) {
			return;
		}
		try {
			Class c = o.getClass();
			Field[] fields = c.getDeclaredFields();
			for (Field f : fields) {
				if (f.getName().equalsIgnoreCase("serialVersionUID")) {
					continue;
				}
				f.setAccessible(true);
				Object value = f.get(o);
				if (value == null) {
					f.set(o, defaultValueMap.get(f.getType().getSimpleName()));
				} 
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

}
